//
//  WSManager.swift
//  SBSafetyApp
//
//  Created by Lina on 2023/1/29.
//

import Foundation
import Starscream
import NotificationBannerSwift
import HandyJSON

struct WSNoticeModal: HandyJSON {
    var noticeId: Int64? // 消息ID
    var noticeTitle: String?  // 标题
    var noticeType: String?  // 类型 1通知 2公告 3系统消息 4系统通知
    var noticeContent: String?  // 内容（没有HTML 标签）
    var mklxdm: String?  // 模块类型代码 1.报警通知、2履职管理、3维保服务、4智慧内保、5一键报修、6台账管理、7检查监督、8智慧保安
    var mkywcj: String?  // 业务场景 1列表 2详情
    var mkywid: String?  // 业务关联ID
}

class WSManager: NSObject {
    static let shared = WSManager()
    var socket: WebSocket?
    
    var isConnected: Bool = false
    
    //初始化
    override init() {
        super.init()
    }
    
    deinit {
        socket?.disconnect()
        socket = nil
    }
    
    func setup() {
        if socket != nil {
            socket?.disconnect()
            socket = nil
            isConnected = false
        }

        if let token = UserDefaults.standard.string(forKey: SafetyToken) {
            var request = URLRequest(url: URL(string: "\(BaseURL)/websocket/\(token)")!)
            request.timeoutInterval = 5
            socket = WebSocket(request: request)
            socket?.delegate = self
            socket?.connect()
        }
    }
    
    private func connect() {
        socket?.connect()
    }
    
    func configNoti(_ model: WSNoticeModal) {
        let param: [String: String] = ["userId": "\(BSUser.currentUser.userId)", "noticeId": "\(model.noticeId!)"]
        do {
            let data: Data = try JSONEncoder().encode(param)
            if let string = String(data: data, encoding: String.Encoding.utf8) {
                socket?.write(string: string, completion: {
                    print("configNoti send", param)
                })
            }           
        } catch {}
        showBanner(model)
    }
    
    func showBanner(_ model: WSNoticeModal) {
        let banner = NotificationBanner(title: model.noticeTitle, subtitle: model.noticeContent?.html2String, style: .info)
        banner.subtitleLabel?.labelize = true
        banner.show()
        banner.onTap = { () -> () in
           // 模块类型代码 1.报警通知、2履职管理、3维保服务、4智慧内保、5一键报修、6台账管理、7检查监督、8智慧保安
            let topNavi = (Utils.app.window?.rootViewController as? UITabBarController)?.selectedViewController as? UINavigationController
            
            if model.noticeType == "1" || model.noticeType == "2" || model.noticeType == "3" {
                topNavi?.pushViewController(NotiDetailVC(id: model.noticeId!), animated: true)
                banner.dismiss(forced: true)
                return
            }
            
            let deptId = BSUser.currentUser.deptId
            let deptName = BSUser.currentUser.deptName
            switch model.mklxdm {
            case "1": // 1.报警通知
                topNavi?.pushViewController(AlarmHomeVC(withDeptId: deptId, deptName: deptName), animated: true)
                break
            case "2": // 履职管理
                topNavi?.pushViewController(TaskHomeVC(withDeptId: deptId, deptName: deptName), animated: true)
                break
            case "3": // 维保服务
                topNavi?.pushViewController(InspListVC(withDeptId: deptId, deptName: deptName, wbtype: model.mkywid), animated: true)
                break
            case "5": // 一键报修
                topNavi?.pushViewController(RepairHomeVC(withDeptId: deptId, deptName: deptName, isSel: true), animated: true)
                break
            case "6": // 台账管理
                topNavi?.pushViewController(ElecLedgerHomeVC(withDeptId: deptId, deptName: deptName), animated: true)
                break
            case "7": // 检查监督
                topNavi?.pushViewController(SuperviseHomeVC(withDeptId: deptId, deptName: deptName, isSel: true), animated: true)
                break
            case "8": // 智慧保安
//                topNavi?.pushViewController(SecurityStatisticsTopVC(withDeptId: deptId, deptName: deptName), animated: true)
                Utils.app.window?.rootViewController = UINavigationController(rootViewController: SecurityHomeVC())
                break
            default: // 4.智慧内保
                break
            }
            
            banner.dismiss(forced: true)
        }
    }
    
//    func addNoti(withTitle title: String, msg: String) {
//        let content = UNMutableNotificationContent()
//        content.title = title
//        content.body = msg
//        content.badge = 1
//        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
//        let request = UNNotificationRequest(identifier: "Notification", content: content, trigger: trigger)
//        UNUserNotificationCenter.current().add(request) { err in
//            err != nil ? print("添加本地通知错误", err!.localizedDescription) : print("添加本地通知成功")
//        }
//    }
}

extension WSManager: WebSocketDelegate {
    func didReceive(event: Starscream.WebSocketEvent, client: Starscream.WebSocketClient) {
        
    }
    
    func didReceive(event: WebSocketEvent, client: WebSocket) {
        switch event {
        case .connected(_):
            isConnected = true
//            print("websocket is connected: \(headers)")
            break
        case .disconnected(let reason, let code):
            isConnected = false
            setup()
            print("websocket is disconnected: \(reason) with code: \(code)")
            break
        case .text(let string):
//            print("Received text: \(string)")
            
            if string.count == 0 {
                isConnected = false
                setup()
            } else {
                let data = string.data(using: .utf8) ?? Data()
                guard let jsonStr = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) else {
                     return
                }
                
                if let data = jsonStr as? [String : Any] {
                    if let m = WSNoticeModal.deserialize(from: data) {
                        configNoti(m)
                    }
                }
            }
            break
        case .binary(let data):
//            print("Received data count: \(data.count)")
//            print("Received data: \(String(data: data, encoding: .utf8) ?? "")")
            if data.count == 0 {
                isConnected = false
                setup()
            } else {
                let respStr = String(data: data, encoding: .utf8)
                if ((respStr?.contains("<heart beat/>")) == true) {
                    socket?.write(data: data, completion: {})
                    return
                }
                
                guard let jsonStr = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) else {
                     return
                }
                
                if let data = jsonStr as? [String : Any] {
                    if let m = WSNoticeModal.deserialize(from: data) {
                        configNoti(m)
                    }
                }
            }
            break
        case .ping(_):
            break
        case .pong(_):
            break
        case .viabilityChanged(_):
            break
        case .reconnectSuggested(_):
            break
        case .cancelled:
            isConnected = false
        case .error(_):
            isConnected = false
//            handleError(error)
//            print("didReceive error: \(error!)")
            setup()
        case .peerClosed:
            isConnected = false
        }
    }
}
